﻿using BattleFury.Lib.GameEvents;
using BattleFury.Lib.Graphics;
using BattleFury.Lib.Network;
using BattleFury.Lib.Network.Packets;
using BattleFury.Lib.Players;
using BattleFury.Lib.ServerPlayer;
using BattleFury.Lib.Tiles;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;

namespace BattleFury.Lib.Bots
{
    public abstract class Bot : GenericPlayer, IEntity
    {
        public delegate List<GenericPlayer> GetVisiblePlayers(GenericPlayer gp);
        public GetVisiblePlayers GetVisiblePlayersHandler;

        private Texture2D _whitePixel;

        public Texture2D Texture { get; set; }
        public bool IsEnabled { get; set; }
        public bool IsVisible { get; set; }
        public float Speed { get; set; }
        public FacingDirection FacingDirection { get; set; }
        public Color Tint { get; set; }
        public int KeyFrame { get; set; }
        public bool ShowBounds { get; set; }

        public Tile[,] FieldOfView { get; set; }
        public int ViewRange { get; set; }
        public bool FieldOfViewIsVisible { get; set; }

        public NetworkClient NetworkClient
        {
            get { return RenderEngine.Get().NetworkClient; }
        }

        public SpriteBatch SpriteBatch
        {
            get { return RenderEngine.Get().SpriteBatch; }
        }

        protected Bot(long Id)
            : base(Id)
        {
            IsEnabled = true;
            IsVisible = true;
            Tint = Color.White;
            Speed = 4f;
            FacingDirection = FacingDirection.South;
            ViewRange = 5;
            FieldOfView = new Tile[ViewRange, ViewRange];
        }

        public virtual void LoadContent()
        {
            _whitePixel = RenderEngine.Get().Textures["WhitePixel"];
        }

        protected void AdvanceKeyFrame()
        {
            KeyFrame++;
            if (KeyFrame > 2) KeyFrame = 0;
        }

        public virtual void Update(GameTime gameTime)
        {
            if (!IsEnabled) return;

        }

        public void Draw(GameTime gameTime)
        {
            if (!IsVisible) return;

            if (FieldOfViewIsVisible)
            {
                var sideViewMax = (int)(ViewRange / 2f);
                for (var i = 0; i < ViewRange; i++)
                {
                    if (FacingDirection == FacingDirection.North || FacingDirection == FacingDirection.South)
                    {
                        for (var y = 0; y < ViewRange; y++)
                        {
                            var dir = 1;
                            if (FacingDirection == FacingDirection.South) dir = -1;
                            for (var s = 0; s <= sideViewMax; s++)
                            {
                                var destRect = new Rectangle(Bounds.X - (s * Bounds.Width), Bounds.Y - (y * Bounds.Height * dir), Bounds.Width, Bounds.Height);
                                SpriteBatch.Draw(_whitePixel, destRect, Color.Blue.WithOpacity(0.1f));
                                if (s == 0) continue;
                                destRect = new Rectangle(Bounds.X + (s * Bounds.Width), Bounds.Y - (y * Bounds.Height * dir), Bounds.Width, Bounds.Height);
                                SpriteBatch.Draw(_whitePixel, destRect, Color.Blue.WithOpacity(0.1f));
                            }

                        }
                    }
                    else if (FacingDirection == FacingDirection.East || FacingDirection == FacingDirection.West)
                    {
                        for (var x = 0; x < ViewRange; x++)
                        {
                            var dir = 1;
                            if (FacingDirection == FacingDirection.East) dir = -1;
                            for (var s = 0; s <= sideViewMax; s++)
                            {
                                var destRect = new Rectangle(Bounds.X - (x * Bounds.Width * dir), Bounds.Y - (s * Bounds.Height), Bounds.Width, Bounds.Height);
                                SpriteBatch.Draw(_whitePixel, destRect, Color.Blue.WithOpacity(0.1f));
                                if (s == 0) continue;
                                destRect = new Rectangle(Bounds.X - (x * Bounds.Width * dir), Bounds.Y + (s * Bounds.Height), Bounds.Width, Bounds.Height);
                                SpriteBatch.Draw(_whitePixel, destRect, Color.Blue.WithOpacity(0.1f));
                            }
                        }
                    }
                }
            }

            if (ShowBounds) SpriteBatch.Draw(_whitePixel, Bounds, Color.Red.WithOpacity(0.5f));

            var srcRect = new Rectangle((int)(KeyFrame * Size.X), (int)((int)FacingDirection * Size.Y), (int)Size.X, (int)Size.Y);

            SpriteBatch.Draw(Texture, Position, srcRect, Tint);
        }

        public void SendMessage(IPacket msg)
        {
            if (NetworkClient != null && NetworkClient.Status == NetConnectionStatus.Connected)
            {
                NetworkClient.SendPacket(msg);
            }
        }



        Vector2 IEntity.Position
        {
            get { return base.Position; }
            set { base.Position = value; }
        }

        Rectangle IEntity.Bounds
        {
            get { return base.Bounds; }
        }
        Vector2 IEntity.Size
        {
            get { return base.Size; }
            set { base.Size = value; }
        }

    }
}